<template>
  <div :ref="refValue" class="s-scroll-view-wrapper">
    <div v-if="showConfig" class="setting"><i class="el-icon-setting"></i></div>
    <ul class="s-scroll-info-lists" :style="{width:listWidth}">
      <li v-for="(item,index) in data" :key="index" :class="{'s-scroll-info-item':true,lf:!vertical,normal: item.class=='normal' ,warn: item.class=='warn'
      ,danger: item.class=='danger'}">
        <span class="s-info-time" v-if="item.time">【{{item.time}}】</span>
        <span class="s-info-value" v-if="item.info">{{item.info}}</span>
        <div class="slot-content">
          <slot :item="item"></slot>
        </div>
      </li>
    </ul>
  </div>
</template>
<script>
  export default {
    name: 'SScrollTextView',
    props: {
      //scrollText的元素变量
      refValue: {
        type: String,
        default: 'scrollEl'
      },
      //是否显示配置 可配置显示轻度、重度、中度；信息滚动的速率  //TODO 还未想好怎么实现
      showConfig: {
        type: Boolean,
        default: false
      },
      //是否开始滚动消息
      startScrollText: {
        type: Boolean,
        default: false
      },
      //消息横向滚动还是纵向滚动,默认消息纵向滚动
      vertical: {
        type: Boolean,
        default: true
      },
      //消息播放方式
      circularType: {
        type: String,
        default: 'normal' //normal：播放到尾，停止播放； circular：播放到尾，再从头播放；alternate：已播放过的消息会放置到最后再不间断循环播放；normalContinuous:不循环播放，父组件持续传消息进行显示
      },
      //消息内容列表
      data: {
        type: Array,
        default: function () {
          return []
        },
      },
      //陆续传入的滚动的消息内容列表
      supplementalData: {
        type: Array,
        default: function () {
          return []
        },
      },
    },
    data() {
      return {
        scrollData: [], //滚动的消息
        // scrollData: [], //陆续传入的滚动的消息
        listWidth: '100%', //信息列表默认宽度
        parentEl: null, //父容器元素
        lisEl: null, //lis元素
        distance: 0, //信息滚动，距离原点的距离
        scrollHeight: 0, //滚动的总高度 ，纵向滚动时使用
        scrollWidth: 0, //滚动的总宽度 ，横向滚动时使用
        timer: null, //消息滚动的定时器id
      };
    },
    watch: {
      startScrollText: {
        handler: function (val) {
          if (val) {
            if (Array.isArray(this.data) && this.data.length != 0) {
              this.init();
            }
          } else {
            this.timer && (this.clearTimer());
          }
        },
        immediate: true
      },
      data: {
        handler: function (val) {
          if (Array.isArray(val) && val.length != 0) {
            this.scrollData = this.deepClone(val);
            this.startScrollText && this.init();
          }
        },
        immediate: true
      },
      supplementalData: {
        handler: function (val) {
          if (this.circularType == 'normalContinuous' && val && val.length != 0) {
            this.scrollData.splice(this.scrollData.length, 0, ...val);
            this.$nextTick(() => {
              this.getStyle();
            })
          }
        },
        immediate: true
      },
    },
    mounted() {

    },
    methods: {
      init() {
        this.distance = 0;
        this.getStyle();
      },
      getStyle() {
        let ct = this.$refs[this.refValue];
        this.parentEl = ct;
        if (ct != null && ct != undefined) {
          let ctStyle = document.defaultView.getComputedStyle(ct);
          if (this.vertical) { //纵向滚动
            this.listWidth = '100%';
            let diff = ct.scrollHeight - parseFloat(ctStyle.height);
            if (diff > 0) {
              this.scrollHeight = diff + 20;
              !this.timer && this.interval();
            }
            if (this.circularType == 'alternate' || this.circularType == 'normalContinuous') {
              let ul = document.getElementsByClassName('s-scroll-info-lists');
              if (ul && ul[0]) {
                let lis = ul[0].getElementsByClassName('s-scroll-info-item');
                if (lis && lis[0]) {
                  this.lisEl = lis;
                }
              }
            }
          } else { //横向滚动
            let ul = document.getElementsByClassName('s-scroll-info-lists');
            if (ul && ul[0]) {
              let lis = ul[0].getElementsByClassName('s-scroll-info-item');
              if (lis && lis[0]) {
                this.lisEl = lis;
                let sum = 0;
                for (let i = 0, len = lis.length; i < len; i++) {
                  let w = document.defaultView.getComputedStyle(lis[i]).width;
                  sum = sum + parseFloat(w);
                }
                this.listWidth = Math.ceil(sum) + 'px';
                setTimeout(() => {
                  let diff = ct.scrollWidth - parseFloat(ctStyle.width);
                  if (diff > 0) {
                    this.scrollWidth = diff + 20;
                    !this.timer && this.interval();
                  }
                }, 1)
              }
            }
          }
        }
      },
      interval() {
        this.timer = setInterval(() => {
          let size = this.vertical ? this.scrollHeight : this.scrollWidth;
          this.distance = this.distance + 2;
          if (this.vertical) {
            this.parentEl.scrollTop = this.distance;
          } else {
            this.parentEl.scrollLeft = this.distance;
          }
          if (this.circularType == 'circular') { //从头开始循环播放
            this.distance >= size && (this.distance = 0); //滚动到了尾部
          } else if (this.circularType == 'normal') { //normal 播放到尾停止
            this.distance >= size && this.clearTimer(); //滚动到了尾部
          } else if (this.circularType == 'alternate') { //轮播播放信息
            let {
              h,
              w
            } = {
              h: document.defaultView.getComputedStyle(this.lisEl[0], null).height,
              w: document.defaultView.getComputedStyle(this.lisEl[0], null).width
            };
            if (this.vertical) {
              if (this.distance >= parseFloat(h)) {
               let tmp = this.scrollData.shift();
                 this.scrollData = this.deepClone(this.scrollData.concat(tmp));
                this.distance = 0;
                this.parentEl.scrollTop = this.distance;
                setTimeout(() => {
                  this.lisEl = document.getElementsByClassName('s-scroll-info-item');
                }, 0)
              }
            } else {
              if (this.distance >= parseFloat(w)) {
                let tmp = this.scrollData.shift();
                 this.scrollData = this.deepClone(this.scrollData.concat(tmp));
                this.distance = 0;
                this.parentEl.scrollLeft = this.distance;
                setTimeout(() => {
                  this.lisEl = document.getElementsByClassName('s-scroll-info-item');
                }, 0)
              }
            }
          } else if (this.circularType == 'normalContinuous') {
            this.distance >= size && this.clearTimer(); //滚动到了尾部
          } else {
            return;
          }
        }, 100)
      },
      clearTimer() {
        clearInterval(this.timer);
        this.timer = null;
      },
      deepClone(obj) {
        if (obj == null || obj == undefined) {
          return;
        }
        let newobj = obj.constructor === Array ? [] : {};
        if (typeof obj !== 'object') {
          return obj;
        }
        else {
          for (let i in obj) {
            newobj[i] = (typeof obj[i] === 'object' ? this.cloneObj(obj[i]) : obj[i]);
          }
        }
        return newobj;
      },
    },
    beforeDestroy() {
      this.clearTimer();
    }
  }
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
  @import "../../../assets/styles/base_style";

  .lf {
    float: left;
  }

  .s-scroll-view-wrapper {
    width: 100%;
    height: 100%;
    /* overflow: hidden; */
    overflow: auto;
    /* position: relative; */
    @include scrollbarStyle();

    .s-scroll-info-lists {
      &:after {
        @include clearFloat;
      }

      /* transition:all linear 0.2s; */
      /* position: absolute; */
      /* width: 2250px; */

      .s-scroll-info-item {
        padding: 5px;
        display: flex;
        justify-content: space-between;

        .slot-content {
          margin: 0 0 0 10px;
        }

        &.normal {
          color: #0efcff;
        }

        &.warn {
          color: #fade1f;
        }

        &.danger {
          color: #ff0000;
        }

        .info-time {
          padding: 0 15px 0 0;
        }
      }

    }
  }
</style>